package com.sunday.common.sharding.sphere.jdbc.study.base.sync;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @Description:
 * @Author: zsy
 * @Create: 2023/4/4 13:52
 */
public class SynchronizeAndClassLock2 {

    /**
     * synchronized分别修饰同一个类的静态方法和当前类时互斥
     *
     * 【结论】两个线程同时分别执行一个被synchronized修饰static方法，一个有synchnized(该类)代码块的static方法，锁生效，
     * 虽然是不同对象，因为两个线程使用的同一个类锁。反过来，如果是修饰的不同类，因为类锁不同，肯定不会互斥，
     * 比如将test2方法的synchronized (ClassLock2.class)这句代码改成synchronized (SynchronizeAndClassLock2.class),此时不会互斥。
     */
    public static void main(String[] args) throws Exception {
        new Thread(() -> {
            // new了一个ClassLock2对象
            new ClassLock2().test1();
            // ClassLock2.test1();
        }).start();

        new Thread(() -> {
            // new了另一个ClassLock2对象
            new ClassLock2().test2();
            // ClassLock2.test2();
        }).start();
    }

}

class ClassLock2 {

    public synchronized static void test1() {
        System.out.println(new Date() + " " + Thread.currentThread().getName() + " begin...");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (Exception e) {
        }
        System.out.println(new Date() + " " + Thread.currentThread().getName() + " end...");
    }

    public static void test2() {
        // 【注意】synchronized (SynchronizeAndClassLock2.class)不会互斥
        synchronized (ClassLock2.class) {
            System.out.println(new Date() + " " + Thread.currentThread().getName() + " begin...");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (Exception e) {
            }
            System.out.println(new Date() + " " + Thread.currentThread().getName() + " end...");
        }
    }
}
